package http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import model.ApiConfigDataModel;
import model.ApiDataModel;
import model.ApiResponseDataModel;
import tool.DataReplace;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by yangxianming on 2015-06-11.
 * 将返回的头和主体,做抓取并存到返回对象ApiResponseDataModel中
 */
public class Response implements ResponseImpl {
    HttpURLConnection conn = null;
    ApiResponseDataModel ardm = null;
    ApiDataModel adm = null;
    ApiConfigDataModel acdm = null;
    String result = "";

    Response(HttpURLConnection conn, ApiDataModel adm, ApiResponseDataModel ardm, ApiConfigDataModel acdm){
        this.conn = conn;
        this.adm = adm;
        this.ardm = ardm;
        this.acdm = acdm;
    }

    @Override
    public void getResponseState() throws Exception{
        System.out.println("state code:" + conn.getResponseCode());
    }

    @Override
    public void getResponseHeader() throws Exception{
        String[] isJsonCheck;
//        循环需要抓取的数据
        for (Map.Entry<String, String> me:adm.catchdata.entrySet()){
            String catchDataKey = me.getKey();
            String catchDataValue = me.getValue();
//            将替换方法写在doOhtersMetter方法中,并在之前调用
//            catchDataValue = DataReplace.replace(acdm, catchDataValue);
//            me.setValue(catchDataValue);    //将替换后的数据放回对象
//            检查key是不是带有json标记,头部不需要做json验证,也不需要sql
            isJsonCheck = catchDataKey.split("\\|");
            if (isJsonCheck[0].equals("json"))
                continue;
            if (isJsonCheck[0].equals("sql"))
                continue;

            Pattern pattern = Pattern.compile(catchDataValue);

//            循环返回头
            for (Map.Entry<String, List<String>> meHeader: conn.getHeaderFields().entrySet()){
//                String headerKey = meHeader.getKey();
                List<String> headerValues = meHeader.getValue();

//                循环 头-值 列表
                for (String value: headerValues){
//                    暂时就先捕获第一个值
                    Matcher matcher = pattern.matcher(value);
                    if (matcher.find()){
                        acdm.config.put(catchDataKey, matcher.group(1));
                    }
                }
            }
        }
        adm.apiResponseDataModel.responseHeader = conn.getHeaderFields();
    }

    @Override
    public void getResponseBody() throws Exception{
        String line;
//        从返回流中拼装字符串
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
        while (( line = reader.readLine()) != null){
            result += line;
        }

//        打印出返回体,过长就截取
//        System.out.println(result);
        if (result.length() > 500){
            String tempResult = result;
            System.out.print(tempResult.substring(0, 20));
            System.out.print("  ... response body too long =.=!!! Please check logs ...  ");
            System.out.println(tempResult.substring(tempResult.length() - 20));
        }else {
            System.out.println(result);
        }

//            从拼装字符串中获取需要的数据
        if (result == null){
            adm.apiResponseDataModel.responseBody = "response body is null";
        }else {
            for (Map.Entry<String, String> me:adm.catchdata.entrySet()) {
                String[] isJsonCheck;
                String catchDataKey = me.getKey();
                String catchDataValue = me.getValue();
//                检查key是不是带有json标记,如果是就做json解释并抓取数据
                isJsonCheck = catchDataKey.split("\\|");
                if (isJsonCheck[0].equals("json")){
                    String jsonReturn = checkJson(result, catchDataValue);
                    if (jsonReturn != null)
                        acdm.config.put(catchDataKey, jsonReturn);
                    continue;
                }
                if (isJsonCheck[0].equals("sql"))
                    continue;

                Pattern pattern = Pattern.compile(catchDataValue);
                Matcher matcher = pattern.matcher(result);
                if (matcher.find()){
                    acdm.config.put(catchDataKey, matcher.group(1));
                }
//                else {
//                    acdm.config.put(catchDataKey, "null");
//                }
            }
        }
        adm.apiResponseDataModel.responseBody = result;
    }

    @Override
    public void doOthersMatter() throws Exception{
//        对sql|标记的key做特殊处理
        for (Map.Entry<String, String> me:adm.catchdata.entrySet()) {
            String catchDataKey = me.getKey();
            String catchDataValue = me.getValue();
//            对数据做替换操作
            catchDataValue = DataReplace.replace(acdm, catchDataValue);
//            检查key是不是带有sql标记
            if (catchDataKey.contains("sql|")){
                me.setValue(catchDataValue);    //将替换后的数据放回对象
                acdm.config.put(catchDataKey, catchDataValue);
            }
        }
    }

    private String checkJson(String json, String jsonPath){
//        json:一个完整的json字符串,jsonPath:通过解析jsonPath从json中获取需要的数据
//        尝试提取json中的字符串
        if (json.contains("{") && json.contains("}")){
            json = json.substring(json.indexOf("{")+1, json.lastIndexOf("}"));
            json = "{" + json + "}";
        }else {
            return null;
        }

        try {
            JSONObject object =  JSON.parseObject(json);
//            String jsonpath = "data|questionDetail|optionScheme|options[3]|id";
            String[] jsonPathArr = jsonPath.split("\\|");
            for (int i=0; i<jsonPathArr.length-1; i++){
                String onePath = jsonPathArr[i];
                int index;
                if (onePath.contains("[") && onePath.contains("]")){
                    String strIndex = onePath.substring(onePath.indexOf("[")+1, onePath.lastIndexOf("]"));
                    onePath = onePath.substring(0, onePath.lastIndexOf("["));
                    JSONArray objectsArr = object.getJSONArray(onePath);
                    if (objectsArr == null) //查出来空值,返回控
                        return null;

                    if (strIndex.equals("last")){
                        index = objectsArr.size() - 1 ;
                    }
//                    else if (false){
////                        以后有需求在扩展[]中的标记
//                    }
                    else {
                        index = Integer.valueOf(strIndex);
                    }
                    object = objectsArr.getJSONObject(index);
                    continue;
                }
                if (object == null) //查出来空值,返回控
                    return null;
                object = object.getJSONObject(onePath);
            }

//            如果在json中压根么有找到需要的路径那就返回null
//            if (object == null)
//                return null;

//            最后一个路径直接转换成map然后把key对应的value直接转换成string输出
            String lastPath = jsonPathArr[jsonPathArr.length - 1];
            for (Map.Entry<String, Object> me:object.entrySet()){
                if (me.getKey().equals(lastPath)){
//                    System.out.println(me.getValue().toString());
                    return me.getValue().toString();
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}
